use lazy_regex::{Lazy, Regex};

use crate::Validator;

pub struct RegexValidator {
    pub regex: &'static Lazy<Regex>,
}

impl Validator<String> for RegexValidator {
    type Error = String;

    fn validate(
        &self,
        ident: Option<&str>,
        name: Option<&str>,
        data: &String,
    ) -> Result<(), Self::Error> {
        if self.regex.is_match(data) {
            return Ok(());
        }
        Err(regex_error(ident, name, data, self.regex.as_str()))
    }
}

fn regex_error(ident: Option<&str>, name: Option<&str>, data: &String, regex: &str) -> String {
    let field = name.or(ident).unwrap_or_default();
    format!("{}期望值规则是: {}, 输入的值是: {}", field, regex, data)
}

#[cfg(test)]
mod tests {
    use lazy_regex::regex;

    use super::*;

    #[test]
    fn test_regex_validator() {
        assert!(
            RegexValidator {
                regex: regex!("^[a-zA-Z0-9_-]{3,16}$"),
            }
            .validate(None, None, &Some("abc".to_string()))
            .is_ok()
        );
    }
}
